﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PaperPluginUtilities;
using System.Diagnostics;
using DeepZoomPivotConstructor.PivotLib;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace t_PivotGeneratorTestHelpers
{
    /// <summary>
    /// Some helpful stuff for checking that an image is properly setup and configured! :-)
    /// </summary>
    public static class ImageChecks
    {
        /// <summary>
        /// Do a quick check of the name and description and make sure they are all "ok".
        /// </summary>
        /// <param name="results"></param>
        public static void CheckNameAndDescription(this IEnumerable<PivotImage> results)
        {
            results.Execute(r => Trace.WriteLine("Picture name: " + r.Name));
            results.Execute(r => Trace.WriteLine("Picture Description: " + r.Description));
            Assert.IsFalse(results.Any(r => r.Name.Length == 0), "Should be no zero length names!");
            Assert.IsFalse(results.Any(r => r.Description.Length == 0), "Should be no zero length descriptions!");
            Assert.IsFalse(results.Any(r => r.Name.ToLower().Replace("steps", "dork").Contains("eps")), "Some figures had name 'eps'");
            Assert.IsFalse(results.Any(r => r.Name.ToLower().Contains("png")), "Some figures had name 'png'");
            Assert.IsFalse(results.Any(r => r.Name.ToLower().Replace("slide-jpg", "dork").Contains("jpg")), "Some figures had name 'jpg'");
            Assert.IsFalse(results.Any(r => r.Name.ToLower().Contains("jpeg")), "Some figures had name 'jpeg'");
            Assert.IsFalse(results.Any(r => r.Name.ToLower().Contains("gif")), "Some figures had name 'gif'");
            Assert.IsFalse(results.Any(r => r.Name == "(linear scale):"), "Bad names (linear scale) exist!");
            Assert.IsFalse(results.Any(r => r.Name.ToLower().Contains("gif")), "Some figures had name 'gif'");
            Assert.IsFalse(results.Any(r => r.Name.Contains("  ")), "Some names contain multiple spaces");
            Assert.IsFalse(results.Any(r => r.Description.Contains("  ")), "Some descriptions contain multiple sapces");
            Assert.IsFalse(results.Any(r => r.Name.EndsWith(":")), "Names end with colons...");
            Assert.IsFalse(results.Any(r => r.Description.EndsWith(":")), "Names end with colons...");
            Assert.IsFalse(results.Any(r => r.Name.Length > 40), "Some names are too long!");
            Assert.IsFalse(results.Any(r => r.Name.Contains("ETand")), "Some name contains ETand rather than ET and");
            Assert.IsFalse(results.Any(r => r.Description.Contains("ETand")), "Some name contains ETand rather than ET and");
            Assert.IsFalse(results.Any(r => r.Name == "<no info>"), "None of the names should be no info!");
            Assert.IsTrue(results.All(r => r.Name.All(c => !char.IsControl(c) || c == '\t')), "Some characters are control characters!");
            Assert.IsTrue(results.All(r => !r.Description.StartsWith(",")), "Some descriptions seems to start with a comma!");
            Assert.IsTrue(results.All(pmi => pmi.Image != null), "Some of the images that came back are null!");
            Assert.IsTrue(results.All(pmi => pmi.Image.IsCompositionUnit), "Not all images are marked as compositional images");
            Assert.IsFalse(results.Any(p => CheckForBadCharacters(p.Name)), "Some names have bad characters!");
            Assert.IsFalse(results.Any(p => CheckForBadCharacters(p.Description)), "Some descriptions have bad characters!");
            foreach (var item in results.Where(p => p.Name.Contains("png")))
            {
                Console.WriteLine("Bad name - has png in it: " + item.Name);
            }
            Assert.IsFalse(results.Any(p => CheckForHTML (p.Name)), "Name contains some HTML looking-stuff");
            Assert.IsFalse(results.Any(p => CheckForHTML(p.Description)), "Description contains some HTML looking-stuff");
        }

        /// <summary>
        /// Check to see if there is somethign that looks like html in the string.
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static bool CheckForHTML(string str)
        {
            if (str.Contains("<!--")) return true;
            return false;
        }

        /// <summary>
        /// There is a certian set of good characters allowed. We figure it out.
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        private static bool CheckForBadCharacters(string str)
        {
            foreach (var c in str)
            {
                if (char.IsControl(c))
                {
                    Trace.WriteLine("Bad name found: " + str);
                    return true;
                }
            }
            return false;
        }

        public static void CheckForStandardMetadata(this IEnumerable<PivotImage> results)
        {
            Assert.AreEqual(0, results.Count(r => FindMetadata<PivotMetadataURL>(r, "Graphics Files").Count() == 0), "Some guys don't have enough graphics files");
            Assert.IsTrue(results.Count(r => FindMetadata<PivotMetadataURL>(r, "More Information").Count() != 1) == 0, "Some don't have a link to main page!");
            Assert.IsTrue(results.Count(r => FindMetadata<PivotMetadataDateTime>(r, "Date").Count() != 1) == 0, "Some don't have a date");
            Assert.AreEqual(0, results.Count(r => FindMetadata<PivotMetadataString>(r, "Note Title").Count() != 1), "Not everyone had a note title");
            Assert.AreEqual(0, results.Count(r => FindMetadata<PivotMetadataString>(r, "Caption").Count() != 1), "Not everyone had a caption either!");
        }

        /// <summary>
        /// Hunt throught the metadata!
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="pmf"></param>
        /// <param name="p"></param>
        /// <returns></returns>
        private static T1[] FindMetadata<T1>(PivotImage pmf, string p)
            where T1 : PivotMetadataBase
        {
            var md = from m in pmf
                     where m.Name == p && m.GetType() == typeof(T1)
                     let masType = (T1)m
                     where masType != null
                     select masType;
            return md.ToArray();
        }

    }
}
